<?php

/*

	WebPhrame - A rudimentary PHP web site framework
	Copyright (c) 2008 Joshua Bodine

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, either version 3 of the
	License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this program.  If not, see
	<http://www.gnu.org/licenses/>.

*/

class Users {
	private $db, $conf, $history;

	public function __construct($db, $conf, $history) {
		$this->db = $db;
		$this->conf = $conf;
		$this->history = $history;
	}

	// User-related functions

	public function getAllUsers() {
	       return $this->db->queryCol("SELECT id FROM ".$this->db->prefix."users");
	}

	public function getUserName($id) {
		if(! $id)
			return false;

		return $this->db->query("SELECT name FROM ".$this->db->prefix."users WHERE id=".$id);
	}

	public function setUserName($id, $name) {
		if(! $id || ! $name || $this->getUserName($id) == $name)
			return false;

		$this->history->log($id, "rename user", $this->getUserName($id)." > ".$name);
		$this->db->query("UPDATE ".$this->db->prefix."users SET name=\"".$name."\" WHERE id=".$id);
	}

	public function getUserID($name) {
		if(! $name)
			return false;

		return $this->db->query("SELECT id FROM ".$this->db->prefix."users WHERE name=\"".$name."\"");
	}

	public function createUser($name, $id=0) {
		if(! $name || $this->getUserID($name) || $this->getUserName($id))
			return false;

		$this->db->query("INSERT INTO ".$this->db->prefix."users SET name=\"".$name."\"".($id ? ",id=".$id : ""));

		$id = $this->getUserID($name);

		if($id) {
			$this->history->log($id, "new account", $id." ".$name);
			return $id;
		}

		return 0;
	}

	public function deleteUser($id) {
		if(! $id)
			return false;

		$this->history->log($id, "delete account", $id." ".$this->getUserName($id));
		$this->db->query("DELETE FROM ".$this->db->prefix."users WHERE id=".$id);
	}

	public function checkPassword($password, $id) {
		if(! $id)
			return false;

		if($this->db->query("SELECT password FROM ".$this->db->prefix."users WHERE id=".$id) == md5($password.$this->conf->get("md5_salt")))
			return true;

		return false;
	}

	public function setPassword($id, $password) {
		if(! $id)
			return false;

		$this->db->query("UPDATE ".$this->db->prefix."users SET password=\"".md5($password.$this->conf->get("md5_salt"))."\" WHERE id=".$id);
	}

	// Group-related functions

	public function getAllGroups() {
		return $this->db->queryCol("SELECT id FROM ".$this->db->prefix."groups");
	}

	public function getGroupID($name) {
		if(! $name)
			return false;

		return $this->db->query("SELECT id FROM ".$this->db->prefix."groups WHERE name=\"".$name."\"");
	}

	public function getGroupName($id) {
		if(! $id)
			return false;

		return $this->db->query("SELECT name FROM ".$this->db->prefix."groups WHERE id=".$id);
	}

	public function setGroupName($id, $creator, $name) {
		if(! $id || ! $name)
			return false;

		$this->history->log($creator, "rename group", $this->getGroupName($id)." > ".$name);
		return $this->db->query("UPDATE ".$this->db->prefix."groups SET name=\"".$name."\" WHERE id=".$id);
	}

	public function createGroup($name, $creator, $priv=1) {
		if(! $name)
			return false;

		$this->db->query("INSERT INTO ".$this->db->prefix."groups SET name=\"".$name."\",priv=".$priv);

		$id = $this->getGroupID($name);
		if($id) {
			$this->history->log($creator, "add group", $name." (".$this->getPrivDescription($priv).")");
			return $id;
		}

		return 0;
	}

	public function deleteGroup($id, $creator) {
		if(! $id)
			return false;

		$this->removeGroupMember($id);
		$this->history->log($creator, "delete group", $this->getGroupName($id)." (".$this->getPrivDescription($this->getGroupPrivLevel($id)).")");
		$this->db->query("DELETE FROM ".$this->db->prefix."groups WHERE id=".$id);
	}

	public function getGroups($id) {
		if(! $id)
			return false;

		return $this->db->queryCol("SELECT groupid FROM ".$this->db->prefix."memberships WHERE userid=".$id);
	}

	public function isGroupMember($groupid, $id) {
		return $this->db->query("SELECT userid FROM ".$this->db->prefix."memberships WHERE userid=".$id." AND groupid=".$groupid);
	}

	public function addGroupMember($groupid, $id) {
		if(! $this->isGroupmember($groupid, $id)) {
			$this->db->query("INSERT INTO ".$this->db->prefix."memberships SET userid=".$id.",groupid=".$groupid);
			$this->history->log($id, "add membership", $this->getGroupName($groupid));
		}
	}

	public function removeGroupMember($groupid, $id=0) {
		if($id) {
			$this->db->query("DELETE FROM ".$this->db->prefix."memberships WHERE groupid=".$groupid." AND userid=".$id);
			$this->history->log($id, "remove membership", $this->getGroupName($groupid));
		} else {
			if(count($this->getGroupMembers($groupid)) > 0) {
				foreach($this->getGroupMembers($groupid) as $member) {
					$this->history->log($member, "remove membership", $this->getGroupName($groupid));
					$this->db->query("DELETE FROM ".$this->db->prefix."memberships WHERE groupid=".$groupid." AND userid=".$member);
				}
			}
		}
	}

	public function getGroupMembers($groupid) {
		if($groupid)
			return $this->db->queryCol("SELECT userid FROM ".$this->db->prefix."memberships WHERE groupid=".$groupid);
	}

	// Privilege-related functions

	public function getUserPrivLevel($id) {
		if(! $id)
			return false;

		return $this->db->query("SELECT priv FROM ".$this->db->prefix."users WHERE id=".$id);
	}

	public function getGroupPrivLevel($id) {
		if(! $id)
			return false;

		return $this->db->query("SELECT priv FROM ".$this->db->prefix."groups where id=".$id);
	}

	public function getPrivLevel($id) {
		if(! $id)
			return false;

		$level = 0;
		$groups	= $this->getGroups($id);

		if(count($groups) > 0)
                        foreach($this->getGroups($id) as $groupid) {
                                $grouplevel = $this->getGroupPrivLevel($groupid);
	                        if($grouplevel > $level)
                                        $level = $grouplevel;
		        }


		$userlevel = $this->getUserPrivLevel($id);
		if($userlevel > $level)
			return $userlevel;

		return $level;
	}

	public function setUserPrivLevel($id, $level) {
		if(! $id || ! $level)
			return false;

		$this->db->query("UPDATE ".$this->db->prefix."users SET priv=".$level." WHERE id=".$id);
	}

	public function setGroupPrivLevel($id, $creator, $level) {
		if(! $id || ! $level)
			return false;

		$this->history->log($creator, "update group role", $this->getGroupName($id)." (".$this->getPrivDescription($this->getGroupPrivLevel($id)).") > (".$this->getPrivDescription($level).")");
		$this->db->query("UPDATE ".$this->db->prefix."groups SET priv=".$level." WHERE id=".$id);
	}

	public function getPrivLevels() {
		return $this->db->queryCol("SELECT priv FROM ".$this->db->prefix."privs");
	}

	public function getPrivDescription($level) {
		if(! $level)
			return false;

		return $this->db->query("SELECT description FROM ".$this->db->prefix."privs WHERE priv=".$level);
	}

	public function setPrivDescription($level, $description) {
		if(! $level || ! $description)
			return false;

		if($this->db->query("SELECT description FROM ".$this->db->privs."privs WHERE priv=".$level))
			$this->db->query("UPDATE ".$this->db->prefix."privs SET description=\"".$description."\" WHERE priv=".$level);
		else
			$this->db->query("INSERT INTO ".$this->db->prefix."privs SET priv=".$level.", description=\"".$description."\"");
	}

	// Action-related functions
	public function canDo($id, $action) {
		if($this->db->query("SELECT priv FROM ".$this->db->prefix."actions WHERE action=\"".$action."\"") == "")
			return false;
		if($this->db->query("SELECT priv FROM ".$this->db->prefix."actions WHERE action=\"".
				$action."\" AND priv<=".$this->getPrivLevel($id)))
			return true;

		return false;
	}

	public function createAction($action, $priv) {
		$this->db->query("INSERT INTO ".$this->db->prefix."actions SET action=\"".
				$action."\",priv=".$priv);
	}

	public function setActionPriv($action, $priv) {
		$oldPriv = $this->db->query("SELECT priv FROM ".$this->db->prefix."actions WHERE action=\"".$action."\"");

		if(isSet($oldPriv)) {
			if($oldPriv != $priv) {
				$this->db->query("UPDATE ".$this->db->prefix."actions SET priv=".$priv." WHERE action=\"".
						$action."\"");
			}
		} else {
			$this->createAction($action, $priv);
		}
	}

	public function deleteAction($action) {
		$this->db->query("DELETE FROM ".$this->db->prefix."actions WHERE action=\"".$action."\"");
	}
}

?>
